package com.webserver.http;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.EmptyStackException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

public class HttpServletRequest {
    private Socket socket;
    private String method,uri,protocol;

    private String requestURI;
    private String queryString;
    private Map<String,String> parameters = new HashMap<>();

    private Map<String,String> headers = new HashMap<>();

    public HttpServletRequest(Socket socket) throws IOException, EmptyRequestException {
        this.socket = socket;

        parseRequestLine();
        parseHeaders();
        parseContent();
    }

    private void parseRequestLine() throws IOException, EmptyRequestException {
        String line = readLine();
        if(line.isEmpty()){
            throw new EmptyRequestException();
        }

        String[] data = line.split("\\s");
        method = data[0];
        uri = data[1];
        protocol = data[2];
        System.out.println("发起请求");
        System.out.println(line);
        parseUri();
    }

    private void parseUri(){
        String[] data= uri.split("\\?");
        requestURI = data[0];
        if(data.length > 1){//如果为post请求，data.length是不大于1的，false
            queryString = data[1];//get拿到参数的方式
            parseParameters(queryString);
        }
        System.out.println("requestURI:"+requestURI);
        System.out.println("queryString:"+queryString);
        System.out.println("parameters:"+parameters);
    }

    private void parseParameters(String queryString){
        try {
            queryString = URLDecoder.decode(queryString,"UTF-8");//将ISO8859-1字符集的16进制转为UTF-8字符串。
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        String[] data = queryString.split("&");
        for (String para : data){
            String[] paraArray = para.split("=");
            String key = paraArray[0];
            String value = paraArray.length>1 ? paraArray[1] : null;
            parameters.put(key,value);//存入请求行的参数

        }
        System.out.println(parameters);
    }

    private void parseHeaders() throws IOException {
        while (true){
            String line = readLine();
            if(line.isEmpty())break;
            String[] data = line.split(":\\s");
            headers.put(data[0].toLowerCase(),data[1]);//存入消息头的参数
            System.out.println(line);
        }


    }

    private void parseContent() throws IOException {
        if("post".equalsIgnoreCase(method)){
            String contentLength = getHeader("content-length");
            if(contentLength != null){
                int length = Integer.parseInt(contentLength);
                System.out.println("正文长度："+length);

                InputStream in = socket.getInputStream();
                byte[] data = new byte[length];
                in.read(data);

                String contentType = getHeader("content-type");

                if ("application/x-www-form-urlencoded".equals(contentType)) {//post请求方式消息头的content-type内容为application/x-www-form-urlencoded
                    String line = new String(data, StandardCharsets.ISO_8859_1);
                    System.out.println("正文内容" + line);//post拿到参数的方式
                    parseParameters(line);
                }


            }
        }
    }

    private String readLine() throws IOException {
        int a;
        char per = 'a',cur;
        StringBuilder line = new StringBuilder();
        InputStream in = socket.getInputStream();
        while ((a = in.read()) != -1){
            cur = (char) a;
            if(cur == 10 && per == 13)break;
            line.append(cur);
            per = cur;
        }
        return line.toString().trim();
    }

    public String getMethod() {
        return method;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public String getUri() {
        return uri;
    }

    public void setUri(String uri) {
        this.uri = uri;
    }

    public String getProtocol() {
        return protocol;
    }

    public void setProtocol(String protocol) {
        this.protocol = protocol;
    }

    public String getRequestURI() {
        return requestURI;
    }

    public String getQueryString() {
        return queryString;
    }

    public String getHeader(String name) {
        return headers.get(name);
    }

    public String getParameter(String name) {
        return parameters.get(name);
    }
}
